package cn.swpu.blog.controller;

import cn.swpu.blog.dao.UserInfoMapper;
import cn.swpu.blog.dto.UserDto;
import cn.swpu.blog.entity.UserInfo;
import cn.swpu.blog.exception.StateErrorException;
import cn.swpu.blog.util.JwtUtil;
import cn.swpu.blog.util.QQHttpClient;

import cn.swpu.blog.vo.ResponseVo;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.net.URLEncoder;
import java.util.UUID;

/**
 * @Author 冰翔
 * @Date 2021/2/19 08:55
 * 不采用restController，最后需要返回的数请求上加上@ResponseBody注解
 */
@Slf4j
@Api(tags = "OAuth QQ登录")
@Controller
public class QQController {

    @Value("${qq.oauth.http}")
    private String http;

    @Autowired
    UserInfoMapper userInfoMapper;

    @Autowired
    JwtUtil jwtUtil;

    /**
     * 发起请求
     * @param session
     * @return
     */
    @GetMapping("/qq/oauth")
    public String qq(HttpSession session){
        //QQ互联中的回调地址
        String backUrl = http + "/qqLogin/callback.do";

        //用于第三方应用防止CSRF攻击
        String uuid = UUID.randomUUID().toString().replaceAll("-","");
        session.setAttribute("state",uuid);

        //Step1：获取Authorization Code
        String url = "https://graph.qq.com/oauth2.0/authorize?response_type=code"+
                "&client_id=" + QQHttpClient.APPID +
                "&redirect_uri=" + URLEncoder.encode(backUrl) +
                "&state=" + uuid;

        return "redirect:" + url;
    }

    /**
     * QQ回调
     * @param request
     * @return
     */
    @GetMapping("/qqLogin/callback.do")
    public String qqcallback(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        //qq返回的信息：http://graph.qq.com/demo/index.jsp?code=9A5F************************06AF&state=test
        String code = request.getParameter(
                "code");
        String state = request.getParameter("state");
        String uuid = (String) session.getAttribute("state");

        /*if(uuid != null){
            if(!uuid.equals(state)){
                throw new StateErrorException("QQ,state错误");
            }
        }*/

        //Step2：通过Authorization Code获取Access Token
        String backUrl = http + "/qqLogin/callback.do";
        String url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code"+
                "&client_id=" + QQHttpClient.APPID +
                "&client_secret=" + QQHttpClient.APPKEY +
                "&code=" + code +
                "&redirect_uri=" + backUrl;

        String access_token = QQHttpClient.getAccessToken(url);

        //Step3: 获取回调后的 openid 值
        url = "https://graph.qq.com/oauth2.0/me?access_token=" + access_token;
        String openid = QQHttpClient.getOpenID(url);

        UserInfo userInfo = userInfoMapper.selectByPrimaryKey(openid);

        //如果为空表示第一次登陆
        if (userInfo == null) {
            //Step4：获取QQ用户信息
            url = "https://graph.qq.com/user/get_user_info?access_token=" + access_token +
                    "&oauth_consumer_key="+ QQHttpClient.APPID +
                    "&openid=" + openid;

            /**
             * jsonObject 包含获取到的QQ信息
             * ret -> {Integer@8040} 0
             * msg ->
             * is_lost -> {Integer@8040} 0
             * "gender" -> "男"
             * "is_yellow_vip" -> "0"
             * "city" -> ""
             * "year" -> "1999"
             * "level" -> "0"
             * "figureurl_2" -> "http://qzapp.qlogo.cn/qzapp/101926184/859F08CE93108E06CEC51032D38B9618/100"
             * "figureurl_1" -> "http://qzapp.qlogo.cn/qzapp/101926184/859F08CE93108E06CEC51032D38B9618/50"
             * "gender_type" -> {Integer@8059} 1
             * "is_yellow_year_vip" -> "0"
             * "province" -> ""
             * "constellation" -> ""
             * "figureurl" -> "http://qzapp.qlogo.cn/qzapp/101926184/859F08CE93108E06CEC51032D38B9618/30"
             * "figureurl_type" -> "1"
             * "figureurl_qq" -> "http://thirdqq.qlogo.cn/g?b=oidb&k=n1UcmntrOhpg5Yd1THAvmA&s=640&t=1611686890"
             * "nickname" -> "冷"
             * "yellow_vip_level" -> "0"
             * "figureurl_qq_1" -> "http://thirdqq.qlogo.cn/g?b=oidb&k=n1UcmntrOhpg5Yd1THAvmA&s=40&t=1611686890"
             * "vip" -> "0"
             * "figureurl_qq_2" -> "http://thirdqq.qlogo.cn/g?b=oidb&k=n1UcmntrOhpg5Yd1THAvmA&s=100&t=1611686890"
             */
            JSONObject jsonObject = QQHttpClient.getUserInfo(url);

            userInfo = new UserInfo(openid, (String)jsonObject.get("nickname"), (String)jsonObject.get("gender"),(String)jsonObject.get("figureurl_qq_2"), 1);
            userInfoMapper.insert(userInfo);
        }

        String token = jwtUtil.createAccessToken(userInfo);

        log.info(userInfo.toString() + "签发的token为" + "Bearer "+token);

        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(userInfo, userDto);
        userDto.setJwt("Bearer "+token);
        //设置jwt
        response.addHeader("Authorization", "Bearer "+token);
        String url2 = "/#/qq/redirect" + "?openid="+openid+ "&nickname=" + userInfo.getNickname()+"&Authorization=" +userDto.getJwt() +"&getFigureurlQq2="+userDto.getFigureurlQq2();
        return "redirect:"+ url2;
    }
}
